home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / tools / sharp / sxwork2.lzh / サンプル基礎編 / 図形表示 / FIGURE.C next >
Text File  |  1994-03-10  |  13KB  |  352 lines

  1. /******************************************************************************
  2.  *    figure.c:    図形の表示
  3.  ******************************************************************************
  4.  *    Workroom SX-68K Sample Program Copyright 1994 SHARP
  5.  *
  6.  *    機能説明:
  7.  *    このプログラムは、ウィンドウを作成し、アップデートイベントで図形を表示
  8.  *    します。
  9.  *    表示する図形は、SXシステムで用意されている長方形、楕円、円弧、面取り
  10.  *    長方形の4種類でそれぞれ枠だけの描画と、中を塗りつぶしたものを描画しま
  11.  *    す。
  12.  */
  13. #include <ctype.h>
  14. #include <stdlib.h>
  15. #include <event.h>        /* イベントマンを利用するときに必要    */
  16. #include <sxgraph.h>        /* グラフ系マネージャを利用するときに必要 */
  17. #include <window.h>        /* ウィンドウマンを利用するときに必要    */
  18. #include <dialog.h>        /* ダイアログマンを利用するときに必要    */
  19. #include <task.h>        /* タスクマンを利用するときに必要    */
  20. #include "figure.h"        /* このプログラム固有のヘッダファイル    */
  21.  
  22. char _sxkernelcomm[] = SXKERNEL;    /* カーネル起動コマンド        */
  23.  
  24. /******************************************************************************
  25.  *    main():        メイン関数
  26.  ******************************************************************************
  27.  */
  28. int main(void)
  29. {
  30.     ComVal cv;            /* 共通変数            */
  31.  
  32.     if (!init(&cv)) {        /* 初期化処理を行う        */
  33.         showErrDialog(&cv);    /* エラーダイアログを表示する    */
  34.         cv.endFlag = TRUE;    /* 終了フラグをセットする    */
  35.     }
  36.     /* 終了フラグがセットされるまでループする */
  37.     while (!cv.endFlag) {
  38.         cv.errorCode = 0;    /* エラーコードをクリアする    */
  39.         /* タスクマンからイベントを取得する */
  40.         TSEventAvail(cv.eventMask, &cv.event);
  41.         /* 各イベントに対応した処理を行う */
  42.         switch (cv.event.ts.what) {
  43.         case E_MSLDOWN:        /* マウスレフトダウンイベント    */
  44.             msLDownEvent(&cv);
  45.             break;
  46.         case E_KEYDOWN:        /* キーダウンイベント        */
  47.             keyDownEvent(&cv);
  48.             break;
  49.         case E_UPDATE:        /* アップデートイベント        */
  50.             updateEvent(&cv);
  51.             break;
  52.         case E_ACTIVATE:    /* アクティベートイベント    */
  53.             activateEvent(&cv);
  54.             break;
  55.         case E_SYSTEM1:        /* システムイベント        */
  56.         case E_SYSTEM2:
  57.             systemEvent(&cv);
  58.             break;
  59.         }
  60.         if (cv.errorCode != 0)    /* エラーが発生したか?        */
  61.             showErrDialog(&cv); /* エラーダイアログを表示する */
  62.     }
  63.     /* 終了手続きを行う */
  64.     endProc(((cv.errorCode == 0) ? EXIT_SUCCESS : EXIT_FAILURE), &cv);
  65.  
  66.     return 0;
  67. }
  68.  
  69. /******************************************************************************
  70.  *    init():        初期化処理
  71.  ******************************************************************************
  72.  *    引数:    ComVal *pcv    共通変数へのポインタ
  73.  *    戻り値:    BOOLEAN        = TRUE:  初期化成功
  74.  *                = FALSE: 初期化失敗(終了)
  75.  *    注釈:    共通変数の初期化、アボート処理関数の登録、ウィンドウの作成と
  76.  *        表示などを行う。
  77.  */
  78. BOOLEAN init(ComVal *pcv)
  79. {
  80.     pcv->windowPtr = NULL;        /* ウィンドウポインタ        */
  81.     pcv->activeFlag = FALSE;    /* アクティブフラグ        */
  82.     pcv->eventMask = EVENTMASK;    /* イベントマスク        */
  83.     pcv->errorCode = 0;        /* エラーコード            */
  84.     pcv->endFlag = FALSE;        /* 終了フラグ            */
  85.  
  86.     TSSetAbort(endProc, (long) pcv); /* アボート処理関数を登録する    */
  87.  
  88.     if (LOWWORD(SXVer()) < SXVER2) { /* SXシステムのバージョンを調べる */
  89.         pcv->errorCode = 1;    /* バージョン2より古い        */
  90.         return FALSE;        /* 失敗したのでFALSEを返す    */
  91.     }
  92.     if (!createWindow(pcv)) {    /* ウィンドウを作成する        */
  93.         pcv->errorCode = 2;    /* 作成できなかった        */
  94.         return FALSE;        /* 失敗したのでFALSEを返す    */
  95.     }
  96.  
  97.     GMSetGraph(&pcv->windowPtr->graph); /* 自分をカレントグラフにする */
  98.     GMForeColor(G_BLACK);        /* フォアグラウンドカラーを黒にする */
  99.     /* バックグラウンドカラーをライトグレーにする */
  100.     GMBackColor(G_LGRAY);
  101.     /* このサンプルでは、図形の描画にカラーを使用するので、アクセスページを
  102.        0~2ページにする */
  103.     GMAPage(G_PAGE0 | G_PAGE1 | G_PAGE2);
  104.  
  105.     WMShow(pcv->windowPtr);        /* ウィンドウを表示する        */
  106.     return TRUE;            /* 成功したのでTRUEを返す    */
  107. }
  108.  
  109. /******************************************************************************
  110.  *    createWindow():    ウィンドウの作成
  111.  ******************************************************************************
  112.  *    引数:    ComVal *pcv    共通変数へのポインタ
  113.  *    戻り値:    BOOLEAN        = TRUE:  作成成功
  114.  *                = FALSE: 作成失敗(終了)
  115.  */
  116. BOOLEAN createWindow(ComVal *pcv)
  117. {
  118.     int paramFlags;            /* パラメータの有無        */
  119.     Rect rc;
  120.     Task task;            /* タスク管理レコード        */
  121.  
  122.     static Rect winSize = { 0, 0, WIN_H, WIN_V }; /* ウィンドウサイズ */
  123.  
  124.     TSGetTdb(&task, TS_OWN);    /* タスク管理レコードを取得する    */
  125.     paramFlags = TSTakeParam(    /* コマンドラインを解析する    */
  126.         task.command,        /* コマンドライン        */
  127.         &rc,            /* 指定されたウィンドウ位置    */
  128.         NULL,            /* 最終文字列を格納しない    */
  129.         0,            /* アドレステーブルを保存しない    */
  130.         NULL,            /* アドレステーブルを作成しない    */
  131.         NULL);            /* ポインタを確保しない        */
  132.     if (!(paramFlags & 1)) {    /* ウィンドウ位置の指定があるか? */
  133.         /* ない場合、システムからウィンドウの左上座標を取得する */
  134.         rc = winSize;
  135.         GMSlideRect(&rc, TSGetWindowPos());
  136.     }
  137.  
  138.     pcv->windowPtr = WMOpen(    /* ウィンドウをオープンする    */
  139.         NULL,            /* ウィンドウポインタを確保する    */
  140.         &rc,            /* ウィンドウの表示位置        */
  141.         WINTITLE,        /* ウィンドウタイトル        */
  142.         FALSE,            /* オープン時に描画しない    */
  143.         WI_STD2 << 4,        /* タイトルの広い標準ウィンドウ    */
  144.         W_FRONT,        /* 一番手前に表示する        */
  145.         TRUE,            /* クローズボタンを使用する    */
  146.         TSGetID());        /* 自分のタスクID        */
  147.     if (pcv->windowPtr == NULL)
  148.         return FALSE;        /* 失敗したのでFALSEを返す    */
  149.  
  150.     return TRUE;            /* 成功したのでTRUEを返す    */
  151. }
  152.  
  153. /******************************************************************************
  154.  *    msLDownEvent():    マウスレフトダウンイベント処理
  155.  ******************************************************************************
  156.  *    引数:    ComVal *pcv    共通変数へのポインタ
  157.  *    注釈:
  158.  *    ウィンドウ上でマウスの左ボタンが押された場合の処理を行う。
  159.  *    この処理でクローズボタンによる終了、ウィンドウの移動が可能となります。
  160.  */
  161. void msLDownEvent(ComVal *pcv)
  162. {
  163.     int partCode;            /* ウィンドウのパートコード    */
  164.     Window *wTemp;            /* テンポラリウィンドウポインタ    */
  165.  
  166.     /* イベントが自分のウィンドウか? */
  167.     if (pcv->event.ev.whom.win == pcv->windowPtr) {
  168.         /* ウィンドウがインアクティブで、OPT.1キーが押されてないか? */
  169.         if (!pcv->activeFlag && !(pcv->event.ev.how & KS_OPT1)) {
  170.             /* ウィンドウをアクティブにする */
  171.             WMSelect(pcv->windowPtr);
  172.             /* ボタンが押された場所のパートコードを取得する */
  173.             partCode = WMFind(pcv->event.ev.where.x_y, &wTemp);
  174.             /* タイトルバー以外か、左ボタンが離されたか? */
  175.             if (partCode != W_INDRAG || !EMLStill())
  176.                 return;
  177.         }
  178.         /* マウスのボタンが押されている間、ウィンドウ上の各種処理を
  179.            システムに任せて、ボタンが押された、または離された場所の
  180.            パートコードを取得する */
  181.         partCode = SXCallWindM(pcv->windowPtr, &pcv->event);
  182.         if (partCode == W_INCLOSE) /* クローズボタンか?    */
  183.             pcv->endFlag = TRUE; /* 終了フラグをセットする    */
  184.     }
  185. }
  186.  
  187. /******************************************************************************
  188.  *    keyDownEvent():    キーダウンイベント処理
  189.  ******************************************************************************
  190.  *    引数:    ComVal *pcv    共通変数へのポインタ
  191.  *    注釈:    OPT.1+'Q'キーでの終了処理を行う。
  192.  */
  193. void keyDownEvent(ComVal *pcv)
  194. {
  195.     int shortCut;            /* ショートカットキー        */
  196.  
  197.     if (pcv->event.ev.how & KS_OPT1) { /* OPT.1キーが押されたか?    */
  198.         /* キー入力した文字を大文字に変換する */
  199.         shortCut = toupper((int) pcv->event.ev.whom.key.ascii);
  200.         if (shortCut == 'Q')    /* 終了か?            */
  201.             pcv->endFlag = TRUE; /* 終了フラグをセットする    */
  202.     }
  203. }
  204.  
  205. /******************************************************************************
  206.  *    updateEvent():    アップデート処理
  207.  ******************************************************************************
  208.  *    引数:    ComVal *pcv    共通変数へのポインタ
  209.  *    注釈:
  210.  *    アップデート処理としてウィンドウ内部を描画する。
  211.  *    この処理を行わないと、自分より下のウィンドウのアップデートやアイドル
  212.  *    イベントの処理ができなくなります。
  213.  */
  214. void updateEvent(ComVal *pcv)
  215. {
  216.     /* イベントが自分のウィンドウか? */
  217.     if (pcv->event.ev.whom.win == pcv->windowPtr) {
  218.         WMUpdate(pcv->windowPtr); /* アップデートを開始する    */
  219.         drawGraph(pcv);        /* ウィンドウ内部を描画する    */
  220.         WMUpdtOver(pcv->windowPtr); /* アップデートを終了する    */
  221.     }
  222. }
  223.  
  224. /******************************************************************************
  225.  *    drawGraph():    ウィンドウ内部の描画
  226.  ******************************************************************************
  227.  *    引数:    ComVal *pcv    共通変数へのポインタ
  228.  */
  229. void drawGraph(ComVal *pcv)
  230. {
  231.     int lastFC;
  232.  
  233.     static Rect fgrPos[] = {    /* 図形の表示位置        */
  234.         { FRM1_X, FRM1_Y, FRM1_X + 50, FRM1_Y + 50 }, /* 長方形    */
  235.         { FLL1_X, FLL1_Y, FLL1_X + 50, FLL1_Y + 50 },
  236.         { FRM2_X, FRM2_Y, FRM2_X + 50, FRM2_Y + 40 }, /* 楕円    */
  237.         { FLL2_X, FLL2_Y, FLL2_X + 50, FLL2_Y + 40 },
  238.         { FLL3_X, FLL3_Y, FLL3_X + 50, FLL3_Y + 50 }, /* 円弧    */
  239.         { FRM3_X, FRM3_Y, FRM3_X + 50, FRM3_Y + 50 },
  240.         { FLL4_X, FLL4_Y, FLL4_X + 50, FLL4_Y + 50 }, /* 面取り長方形 */
  241.         { FRM4_X, FRM4_Y, FRM4_X + 50, FRM4_Y + 50 }
  242.     };
  243.  
  244.     GMSetGraph(&pcv->windowPtr->graph); /* 自分をカレントグラフにする */
  245.  
  246.     lastFC = GMForeColor(G_RED);    /* フォアグラウンドカラーを赤にする */
  247.     GMFrameRect(&fgrPos[0]);    /* 第1の長方形は枠だけ描く    */
  248.     GMFillRect(&fgrPos[1]);        /* 第2の長方形は塗りつぶしで描く */
  249.     GMForeColor(G_GREEN);        /* フォアグラウンドカラーを緑にする */
  250.     GMFrameOval(&fgrPos[2]);    /* 第1の楕円は枠だけ描く    */
  251.     GMFillOval(&fgrPos[3]);        /* 第2の楕円は塗りつぶしで描く    */
  252.     GMForeColor(G_BLUE);        /* フォアグラウンドカラーを青にする */
  253.     GMFillArc(&fgrPos[4], 90, 0);    /* 第1の円弧は塗りつぶしで描く    */
  254.     GMFrameArc(&fgrPos[5], 0, 270);    /* 第2の円弧は枠だけ描く    */
  255.     GMForeColor(G_YELLOW);        /* フォアグラウンドカラーを黄色にする */
  256.     /* 第1の円弧は塗りつぶしで描く */
  257.     GMFillRRect(&fgrPos[6], LONGWORD(10, 10));
  258.     GMFrameRRect(&fgrPos[7], LONGWORD(10, 10)); /* 第2の楕円は枠だけ描く */
  259.     GMForeColor(lastFC);        /* フォアグラウンドカラーを元に戻す */
  260. }
  261.  
  262. /******************************************************************************
  263.  *    activateEvent():    アクティベートイベント処理
  264.  ******************************************************************************
  265.  *    引数:    ComVal *pcv    共通変数へのポインタ
  266.  *    注釈:    アクティブ、インアクティブによるアクティブフラグの切り替えと、
  267.  *        イベントマスクの切り替えを行う。
  268.  */
  269. void activateEvent(ComVal *pcv)
  270. {
  271.     /* イベントが自分のウィンドウか? */
  272.     if (pcv->event.ev.whom.win == pcv->windowPtr) {
  273.         pcv->activeFlag = TRUE;    /* アクティブフラグをセットする    */
  274.         /* アクティブ時のイベントマスクをセットする */
  275.         pcv->eventMask = EVENTMASK | EM_KEYDOWN;
  276.     /* イベントが他のウィンドウで、自分がアクティブ状態か? */
  277.     } else if (pcv->activeFlag) {
  278.         pcv->activeFlag = FALSE; /* アクティブフラグをクリアする */
  279.         /* インアクティブ時のイベントマスクをセットする */
  280.         pcv->eventMask = EVENTMASK;
  281.     }
  282. }
  283.  
  284. /******************************************************************************
  285.  *    systemEvent():    システムイベント処理
  286.  ******************************************************************************
  287.  *    引数:    ComVal *pcv    共通変数へのポインタ
  288.  *    注釈:    全ウィンドウのクローズ、全タスクの終了、ウィンドウのセレクトに
  289.  *        対応した処理を行う。
  290.  */
  291. void systemEvent(ComVal *pcv)
  292. {
  293.     switch (pcv->event.ts.what2) {    /* イベントの種類は?        */
  294.     case CLOSEALL:            /* 全ウィンドウのクローズ    */
  295.     case ENDTSK:            /* 全タスクの終了        */
  296.         pcv->endFlag = TRUE;    /* 終了フラグをセットする    */
  297.         break;
  298.     case WINDOWSELECT:        /* ウィンドウのセレクト        */
  299.         WMSelect(pcv->windowPtr); /* ウィンドウをアクティブにする */
  300.         break;
  301.     }
  302. }
  303.  
  304. /******************************************************************************
  305.  *    showErrDialog():    エラーダイアログの表示
  306.  ******************************************************************************
  307.  *    引数:    ComVal *pcv    共通変数へのポインタ
  308.  */
  309. void showErrDialog(ComVal *pcv)
  310. {
  311.     int i;
  312.  
  313.     static struct {            /* エラー情報            */
  314.         int code;        /* エラーコード            */
  315.         int manager;        /* 使用するマネージャ        */
  316.         int flag;        /* 表示フラッグ            */
  317.         char *message;        /* エラーメッセージ        */
  318.     } errInfo[] = {
  319.         { 1, 1, D_RED,    "SX SYSTEMのバージョンが違います。" },
  320.         { 2, 2, D_RED,    "ウィンドウが作成できません。" },
  321.         { 0, 1, D_YELLOW, "エラーが発生しました。" }
  322.     };
  323.  
  324.     for (i = 0; errInfo[i].code != 0; i++) /* エラーコードを捜す    */
  325.         if (errInfo[i].code == pcv->errorCode)
  326.             break;
  327.     switch (errInfo[i].manager) {    /* マネージャの選択        */
  328.     case 1:                /* ダイアログマン        */
  329.         DMError(errInfo[i].flag | D_CONFIRM, errInfo[i].message);
  330.         break;
  331.     case 2:                /* タスクマン            */
  332.         TSErrDialogN(errInfo[i].flag | D_CONFIRM, errInfo[i].message);
  333.         break;
  334.     }
  335. }
  336.  
  337. /******************************************************************************
  338.  *    endProc():    終了手続き
  339.  ******************************************************************************
  340.  *    引数:    int code    終了コード
  341.  *        ComVal *pcv    共通変数へのポインタ
  342.  *    注釈:    ハンドルの解放やウィンドウの廃棄と、プログラムの終了を行う。
  343.  */
  344. void endProc(int code, ComVal *pcv)
  345. {
  346.     /* ウィンドウポインタが確保されたままか? */
  347.     if (pcv->windowPtr != NULL)
  348.         WMDispose(pcv->windowPtr); /* ウィンドウを廃棄する    */
  349.  
  350.     exit(code);            /* プログラムを終了する        */
  351. }
  352.